<?php
namespace libs\PHPCan;

defined('ANS') or die();

class MysqlActions extends \PHPUnit_Framework_TestCase
{
	protected $Db;
	protected $Data;
	protected $Debug;
	protected $Errors;
	protected $Lipsum;
	protected $Config;
	protected $tables = array('posts', 'users', 'comments', 'categories', 'formats');
	protected $formats = array('boolean', 'codefile', 'date', 'datetime', 'email', 'enum', 'file', 'float', 'gmaps', 'html', 'id_text', 'image', 'integer', 'ip', 'password', 'realfile', 'sort', 'text', 'title', 'url', 'varchar');

	public function __construct () {
		global $Db, $Data, $Errors, $Lipsum, $Debug, $Config;

		$this->Db = $Db;
		$this->Data = $Data;
		$this->Debug = $Debug;
		$this->Config = $Config;
		$this->Errors = $Errors;
		$this->Lipsum = $Lipsum;

		$this->resetTables();
	}

	public function message ($value) {
		if (is_array($value)) {
			$return = array();

			foreach ($value as $each) {
				$return[] = $this->message($each);
			}

			return implode("\n\n", $return);
		}

		$len = strlen($value);
		$value = ($len > 100) ? (substr($value, 0, 100).' ('.($len - 100).' more)...') : $value;

		return "\n".'Value: '.$value."\n".'Type: '.gettype($value)."\n".'Error: '.implode(', ', $this->Errors->getList())."\n";
	}

	public function resetTables ($insert = 0) {
		$exists_db_query = method_exists($this->Db, 'query');

		foreach ($this->tables as $tables_value) {
			if ($exists_db_query) {
				$this->Db->query('TRUNCATE '.$tables_value.';');
			} else {
				$this->Db->Database->query('TRUNCATE '.$tables_value.';');
			}
		}

		if ($exists_db_query) {
			$this->Db->query('TRUNCATE categories_posts;');
		} else {
			$this->Db->Database->query('TRUNCATE categories_posts;');
		}

		if (is_integer($insert)) {
			for ($i = 0; $i < $insert; $i++) {
				foreach ($this->tables as $tables_value) {
					$method = 'insert'.$tables_value;

					if (method_exists($this, $method)) {
						$this->$method();
					}
				}
			}
		}
	}

	public function insertPosts ($users = null, $comments = null, $categories = null) {
		$relate = array();

		if ($users) {
			$relate[] = array(
				'table' => 'users',
				'conditions' => array(
					'id' => $users
				)
			);
		}
		
		if ($comments) {
			$relate[] = array(
				'table' => 'comments',
				'conditions' => array(
					'id' => $comments
				)
			);
		}

		if ($categories) {
			$relate[] = array(
				'table' => 'categories',
				'conditions' => array(
					'id' => $categories
				)
			);
		}
		
		$query = array(
			'table' => 'posts',
			'data' => array(
				'title' => $this->Lipsum->getContent(10, 'plain'),
				'text' => $this->Lipsum->getContent(500),
				'date' => date('Y-m-d H:i:s'),
				'enabled' => 1
			),
			'relate' => $relate
		);

		return $this->Db->insert($query);
	}

	public function insertComments ($users = null, $posts = null) {
		$relate = array();

		if ($users) {
			$relate[] = array(
				'table' => 'users',
				'conditions' => array(
					'id' => $users
				)
			);
		}
		
		if ($posts) {
			$relate[] = array(
				'table' => 'posts',
				'conditions' => array(
					'id' => $posts
				)
			);
		}
		
		$query = array(
			'table' => 'comments',
			'data' => array(
				'text' => $this->Lipsum->getContent(500),
				'date' => date('Y-m-d H:i:s'),
				'enabled' => 1
			),
			'relate' => $relate
		);

		return $this->Db->insert($query);
	}

	public function insertCategories ($posts = null) {
		$relate = array();

		if ($posts) {
			$relate[] = array(
				'table' => 'posts',
				'conditions' => array(
					'id' => $posts
				)
			);
		}
		
		$query = array(
			'table' => 'categories',
			'data' => array(
				'name' => $this->Lipsum->getContent(3),
				'enabled' => 1
			),
			'relate' => $relate
		);

		return $this->Db->insert($query);
	}

	public function insertUsers ($posts = null, $comments = null) {
		$relate = array();

		if ($posts) {
			$relate[] = array(
				'table' => 'posts',
				'conditions' => array(
					'id' => $posts
				)
			);
		}
		
		if ($comments) {
			$relate[] = array(
				'table' => 'comments',
				'conditions' => array(
					'id' => $comments
				)
			);
		}
		
		$query = array(
			'table' => 'users',
			'data' => array(
				'name' => $this->Lipsum->getContent(3, 'plain'),
				'email' => (md5(microtime().rand(0, 10000)).'@lipsum.com'),
				'enabled' => 1
			),
			'relate' => $relate
		);

		return $this->Db->insert($query);
	}

	public function deletePosts ($conditions = null, $limit = 1) {
		if (!$conditions) {
			$conditions = 'all';
		}
		
		$query = array(
			'table' => 'posts',
			'conditions' => $conditions,
			'limit' => $limit
		);

		return $this->Db->delete($query);
	}

	public function deleteComments ($conditions = null, $limit = 1) {
		if (!$conditions) {
			$conditions = 'all';
		}
		
		$query = array(
			'table' => 'comments',
			'conditions' => $conditions,
			'limit' => $limit
		);

		return $this->Db->delete($query);
	}

	public function deleteUsers ($conditions = null, $limit = 1) {
		if (!$conditions) {
			$conditions = 'all';
		}
		
		$query = array(
			'table' => 'users',
			'conditions' => $conditions,
			'limit' => $limit
		);

		return $this->Db->delete($query);
	}

	public function relatePosts ($posts, $users = null, $comments = null, $categories = null) {
		if ($users) {
			$query = array(
				'tables' => array(
					array(
						'table' => 'posts',
						'conditions' => array(
							'id' => $posts
						)
					),
					array(
						'table' => 'users',
						'conditions' => array(
							'id' => $users
						)
					)
				)
			);

			$this->Db->relate($query);
		}

		if ($comments) {
			$query = array(
				'tables' => array(
					array(
						'table' => 'posts',
						'conditions' => array(
							'id' => $posts
						)
					),
					array(
						'table' => 'comments',
						'conditions' => array(
							'id' => $comments
						)
					)
				)
			);

			$this->Db->relate($query);
		}

		if ($categories) {
			$query = array(
				'tables' => array(
					array(
						'table' => 'posts',
						'conditions' => array(
							'id' => $posts
						)
					),
					array(
						'table' => 'categories',
						'conditions' => array(
							'id' => $categories
						)
					)
				)
			);

			$this->Db->relate($query);
		}

		if ($users && $comments) {
			$query = array(
				'tables' => array(
					array(
						'table' => 'users',
						'conditions' => array(
							'id' => $users
						)
					),
					array(
						'table' => 'comments',
						'conditions' => array(
							'id' => $comments
						)
					)
				)
			);

			$this->Db->relate($query);
		}
	}

	public function getContents ($tables = array(), $relations = false, $random = true) {
		$return = array();

		if ($tables == 'all') {
			$tables = $this->tables;
		} else if (is_string($tables)) {
			$tables = array($tables);
		}

		foreach ($tables as $tables_value) {
			$add_tables = array();

			if ($relations) {
				switch ($tables_value) {
					case 'posts':
						$add_tables[] = array('table' => 'categories');
						$add_tables[] = array('table' => 'users');
						$add_tables[] = array('table' => 'comments');

						break;
					case 'users':
						$add_tables[] = array('table' => 'posts');
						$add_tables[] = array('table' => 'comments');

						break;
					case 'comments':
					case 'categories':
						$add_tables[] = array('table' => 'posts');

						break;
					default:
						continue;
				}
			}

			$return[$tables_value] = $this->Db->select(array(
				'table' => $tables_value,
				'fields' => 'id',
				'add_tables' => $add_tables
			));

			if ($random) {
				shuffle($return[$tables_value]);
			}
		}

		return $return;
	}

	public function testTotals ($Db) {
		$str = __('Total queries %s', count($Db->queryRegister()));
		$cnt = strlen($str) + 4;

		echo "\n\n".str_repeat('-', $cnt)."\n| ".$str." |\n".str_repeat('-', $cnt)."\n\n";
	}
}
